import 'dart:math';
class PPGService {
  // 常量定义
  static const int FS = 50;
  static const int ST = 10;
  static const int BUFFER_SIZE = FS * ST;

  // 辅助函数：计算平均值
  static double _average(List<double> list) {
    return list.reduce((a, b) => a + b) / list.length;
  }

  // RMS 计算
  static Map<String, double> rfRms(List<double> data) {
    double sumSq = 0.0;
    for (final value in data) {
      sumSq += value * value;
    }
    sumSq /= data.length;
    final rms = sqrt(sumSq);
    return {'rms': rms, 'sumSq': sumSq};
  }

  // AMPD 算法实现
  static List<int> ampd(List<double> data) {
    final pData = List<int>.filled(data.length, 0);
    final count = data.length;
    final arrRowSum = <int>[];

    // 第一步：计算不同窗口长度的行和
    for (int k = 1; k <= count ~/ 2; k++) {
      int rowSum = 0;
      for (int i = k; i < count - k; i++) {
        if (data[i] > data[i - k] && data[i] > data[i + k]) {
          rowSum -= 1;
        }
      }
      arrRowSum.add(rowSum);
    }

    // 找到最小行和对应的窗口长度
    final minIndex = _argmin(arrRowSum);
    final maxWindowLength = minIndex + 1; // +1 因为索引从0开始

    // 第二步：标记符合条件的峰值
    for (int k = 1; k <= maxWindowLength; k++) {
      for (int i = k; i < count - k; i++) {
        if (data[i] > data[i - k] && data[i] > data[i + k]) {
          pData[i] += 1;
        }
      }
    }

    // 找到最终峰值索引
    return _findPeaks(pData, maxWindowLength);
  }

  // 辅助函数：找最小值索引
  static int _argmin(List<int> list) {
    int minVal = list[0];
    int minIndex = 0;
    for (int i = 1; i < list.length; i++) {
      if (list[i] < minVal) {
        minVal = list[i];
        minIndex = i;
      }
    }
    return minIndex;
  }

  // 辅助函数：查找符合条件的峰值索引
  static List<int> _findPeaks(List<int> pData, int threshold) {
    final peaks = <int>[];
    for (int i = 0; i < pData.length; i++) {
      if (pData[i] == threshold) {
        peaks.add(i);
      }
    }
    return peaks;
  }


  // 心率计算
  static Map<String, dynamic> calculateHeartRate(List<double> data) {
    final peaks = ampd(data);
    if (peaks.length < 2) {
      return {'hr': -1, 'valid': -1};
    }

    // 计算间隔（秒）
    final intervals = <double>[];
    for (int i = 1; i < peaks.length; i++) {
      final interval = (peaks[i] - peaks[i - 1]) / FS;
      if (interval >= 60 / 150 && interval <= 60 / 40) {
        intervals.add(interval);
      }
    }

    if (intervals.isEmpty) {
      return {'hr': -1, 'valid': -1};
    }

    // 计算中位数心率
    intervals.sort();
    final medianInterval = intervals[intervals.length ~/ 2];
    final hr = 60 / medianInterval;
    if (hr < 40 || hr > 180) {
      return {'hr': -1, 'valid': -1};
    }

    return {
      'hr': hr,
      'valid': 1 
    };
  
  }

  // 血氧和心率综合计算
  static Map<String, dynamic> calculateMetrics(
      List<double> irBuffer, List<double> redBuffer) {
    // 计算直流分量
    final irMean = _average(irBuffer);
    final redMean = _average(redBuffer);

    // 去除直流分量
    final anX = irBuffer.map((v) => v - irMean).toList();
    final anY = redBuffer.map((v) => v - redMean).toList();

    // 计算 RMS
    final xMetrics = rfRms(anX);
    final yMetrics = rfRms(anY);

    // 计算心率
    final hrResult = calculateHeartRate(anX);

    // 计算血氧
    final ratio = (yMetrics['rms']! * irMean) / (xMetrics['rms']! * redMean);
    double spo2 = -1;
    int spo2Valid = -1;

    if (ratio > 0.02 && ratio < 0.84) {
      spo2 = (-45.060 * ratio + 30.354) * ratio + 94.845;
      spo2 = spo2.clamp(95, 100); // 限制在合理范围
      spo2Valid = 1;
    }

    return {
      'spo2': spo2,
      'spo2Valid': spo2Valid,
      'hr': hrResult['hr'],
      'hrValid': hrResult['valid']
    };
    }






}